﻿using System;
using System.Threading;
using System.Windows.Forms;
using MediaPortal.GUI.Library;
using MediaPortal.Profile;
using MediaPortal.Services;
using MediaPortal.Configuration;

namespace ProcessPlugins.MPStartIt
{
    /// <summary>
    /// This plug-in use the option in MediaPortal "showlastactivemodule" to start any plugin
    /// </summary>
    /// <author>rekenaar, Cheezey</author>
    public class MPStartIt : ISetupForm, IPluginReceiver
    {
        #region constants

        private const int WM_POWERBROADCAST = 0x0218;
        private const int WM_QUERYENDSESSION = 0x0011;
        private const int PBT_APMQUERYSUSPEND = 0x0000;
        private const int PBT_APMQUERYSTANDBY = 0x0001;
        private const int PBT_APMQUERYSUSPENDFAILED = 0x0002;
        private const int PBT_APMQUERYSTANDBYFAILED = 0x0003;
        private const int PBT_APMSUSPEND = 0x0004;
        private const int PBT_APMSTANDBY = 0x0005;
        private const int PBT_APMRESUMECRITICAL = 0x0006;
        private const int PBT_APMRESUMESUSPEND = 0x0007;
        private const int PBT_APMRESUMESTANDBY = 0x0008;
        private const int PBT_APMRESUMEAUTOMATIC = 0x0012;

        #endregion

        #region variables

        private const int WindowID = 7171; //The ID for this plugin
        private static ILog _log;
        private bool _enabled;
        private int _idToStart;
        private bool _started;
        private ManualResetEvent _stopEvent;

        #endregion variables

        #region IPlugin implementation

        /// <summary>
        /// This method will be called by mediaportal to start our process plugin
        /// </summary>
        public void Start()
        {
            Microsoft.Win32.SystemEvents.PowerModeChanged += new Microsoft.Win32.PowerModeChangedEventHandler(SystemEventsPowerModeChanged);
            ServiceProvider services = GlobalServiceProvider.Instance;
            _log = services.Get<ILog>();
            _log.Info("plugin: MPStartIt - starting...");
            
            try
            {
                LoadSettings();

                if (_enabled)
                {
                    if (_started) //Already started?
                    {
                        return;
                    }
                    ThreadStart();
                }
            }
            catch (Exception ex)
            {
                _log.Error("plugin: MPStartIt.Start.Ex: " + ex.Message);
            }
        }
        
        /// <summary>
        /// This method will be called by mediaportal to stop the process plugin
        /// </summary>
        public void Stop()
        {
            _log.Info("plugin: MPStartIt stopping...");
            try
            {
                if (!_started)
                {
                    return;
                }
                _stopEvent.Set();
                _started = false;
            }
            catch (Exception ex)
            {
                _log.Error("plugin: MPStartIt.Stop.Ex: " + ex.Message);
            }
            _log.Info("plugin: MPStartIt stopped.");
        }

        public bool WndProc(ref Message msg)
        {
            if (msg.Msg == WM_POWERBROADCAST)
            {
                switch (msg.WParam.ToInt32())
                {
                    case PBT_APMSTANDBY:
                    case PBT_APMSUSPEND:
                    case PBT_APMQUERYSUSPEND:
                    case PBT_APMQUERYSTANDBY:
                        Log.Info("plugin: MPStartIt.WndProc(): Windows is going into powerstate (hibernation/standby)");
                        break;
                    case PBT_APMRESUMESUSPEND:
                        Log.Info("plugin: MPStartIt.WndProc(): Windows has resumed from hibernate mode");
                        ThreadStart();
                        break;
                    case PBT_APMRESUMESTANDBY:
                        Log.Info("plugin: MPStartIt.WndProc(): Windows has resumed from standby mode");
                        ThreadStart();
                        break;
                }
            }
            return false; // false = all other processes will handle the msg
        }


        #endregion

        #region Implementation

        private void LoadSettings()
        {
            using (var xmlreader = new Settings(Config.GetFile(Config.Dir.Config, "MediaPortal.xml")))
            {
                _enabled = xmlreader.GetValueAsBool("plugins", "MPStartIt", false);
                _idToStart = xmlreader.GetValueAsInt("MPStartIt", "idToStart", 0);

                _log.Info("plugin: MPStartIt enabled=" + _enabled.ToString());
                _log.Info("plugin: MPStartIt idToStart=" + _idToStart.ToString());
            }
        }

        private void ThreadStart()
        {
            _stopEvent = new ManualResetEvent(false);
            ThreadPool.QueueUserWorkItem(Worker);
            _started = true;
            _log.Debug("plugin: MPStartIt plugin started.");
        }

        private void Worker(object stateInfo)
        {
            _log.Info("plugin: MPStartIt.Worker busy...");
            try
            {
                if (_idToStart != 0)
                {
                    using (var xmlwriter = new Settings(Config.GetFile(Config.Dir.Config, "MediaPortal.xml")))
                    {
                        xmlwriter.SetValue("general", "showlastactivemodule", "yes");
                        xmlwriter.SetValue("general", "lastactivemodule", _idToStart);
                    }
                }
            }
            catch (Exception e)
            {
                _log.Error("plugin: MPStartIt.Worker.Ex: " + e.Message);
            }
            _log.Info("plugin: MPStartIt.Worker done.");

            // stop plugin - no need to run pass startup period.
            Stop();
        }

        #endregion Implementation

        #region IPluginReceiver Member

        /// <summary>
        /// System power mode has changed
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void SystemEventsPowerModeChanged(object sender, Microsoft.Win32.PowerModeChangedEventArgs e)
        {
            
            switch (e.Mode)
            {
                case Microsoft.Win32.PowerModes.Resume:
                    ThreadStart();
                    break;
                case Microsoft.Win32.PowerModes.Suspend:
                    break;
            }
        }

        #endregion

        #region ISetupForm Members

        string ISetupForm.Author()
        {
            return "rekenaar, Cheezey";
        }

        bool ISetupForm.CanEnable()
        {
            return true;
        }

        bool ISetupForm.DefaultEnabled()
        {
            return false;
        }

        string ISetupForm.Description()
        {
            return "Always start MediaPortal in a specific plugin screen.";
        }

        bool ISetupForm.GetHome(out string strButtonText, out string strButtonImage, out string strButtonImageFocus, out string strPictureImage)
        {
            strButtonText = null;
            strButtonImage = null;
            strButtonImageFocus = null;
            strPictureImage = null;
            return false;
        }

        int ISetupForm.GetWindowId()
        {
            return WindowID;
        }

        bool ISetupForm.HasSetup()
        {
            return true;
        }

        string ISetupForm.PluginName()
        {
            return "MPStartIt";
        }

        void ISetupForm.ShowPlugin()
        {
            Form settings = new SetupForm();
            settings.ShowDialog();
        }

        #endregion
    }
}